<script setup lang="ts">

import { PlusOutlined, LoadingOutlined } from '@ant-design/icons-vue'
import { ref, watch } from 'vue'
import { message, Upload } from 'ant-design-vue'
import { RcFile, UploadRequestOption } from 'ant-design-vue/es/vc-upload/interface'
import { fileToBase64 } from '../../utils/file'

const props = defineProps<{
  value: string,
}>()
const emits = defineEmits<{
  (e: 'change', ...args: any[]): void;
  (e: 'update:value', ...args: any[]): void;
}>()

// 上传图片的url
const valueRef = ref<string>(props.value)

// 上传按钮的背景色, 有值时为白色，无值时为灰色
const backColor = ref<string>('#f5f5f5')

// 上传按钮的loading状态
const loading = ref<boolean>(false)
// 上传的文件列表
const fileList = ref([])

const uploadRef = ref<InstanceType<typeof Upload>>()

/**
 * 自定义上传请求处理函数
 * @param options 上传请求参数
 */
const httpRequestHandle = (options: UploadRequestOption) => {
  loading.value = true
  let { file } = options
  // @ts-ignore 处理上传文件和父级表单校验冲突的bug
  uploadRef.value?.$parent?.$parent?.$parent?.$parent?.$parent?.clearValidate()
  // 转base64
  fileToBase64(file as File).then((res) => {
    loading.value = false
    console.log(res)
    valueRef.value = res
  })

}
/**
 * 上传前的校验函数
 * @param file 上传的文件
 * @param _files 上传的文件列表
 */
const beforeUpload = (file: RcFile, _files: RcFile[]) => {
  const type = file.type
  const isJpgOrPng =
    type === 'image/jpeg' ||
    type === 'image/png' ||
    type === 'image/webp' ||
    type === 'image/jpg'
  if (!isJpgOrPng) {
    message.error('只允许上传jpeg、png、jpg、webp格式的文件！')
  }
  return isJpgOrPng
}

watch(() => props.value, (newValue) => {
  valueRef.value = newValue
})

// 监听valueRef变化，更新上传按钮的背景色, 并且触发change和update:value事件
watch(valueRef, (newValue) => {
  if (newValue) {
    backColor.value = 'transparent'
  } else {
    backColor.value = '#f5f5f5'
  }
  emits('update:value', newValue)
  emits('change', newValue)
})

</script>

<template>
  <div class="upload-container">
    <a-upload
      ref="uploadRef"
      v-bind="$attrs"
      v-model:file-list="fileList"
      v-model="valueRef"
      name="avatar"
      list-type="picture-card"
      :show-upload-list="false"
      action="#"
      class="upload-btn"
      :maxCount="1"
      :before-upload="beforeUpload"
      :customRequest="httpRequestHandle">
      <div>

      </div>
      <img v-if="valueRef" :src="valueRef" alt="avatar" class="ant-image-img" />
      <div v-else>
        <loading-outlined v-if="loading"></loading-outlined>
        <plus-outlined v-else style="font-size: 20px"></plus-outlined>
      </div>
    </a-upload>
  </div>


</template>

<style scoped>
.upload-container {
  width: 100px;
  height: 100px;
  box-shadow: 0 0 4px rgba(0, 0, 0, 0.1);
  text-align: center;
  border-radius: 10px;
}

:deep(.upload-btn) .ant-upload {
  width: 70px !important;
  height: 70px !important;
  border: none !important;
  margin: 8px 0 0 0 !important;
  background-color: v-bind(backColor) !important;
}

.ant-image-img {
  width: 100px;
  height: 100px !important;
  border-radius: 10px;
}
</style>
